//
//  HBPublishViewController.swift
//  sinaWeibo
//
//  Created by Beans on 16/6/30.
//  Copyright © 2016年 iceWorks. All rights reserved.
//

import UIKit
import SVProgressHUD

let placeHoldString = "听说下雨天吃东西更容易长胖哦"

class HBPublishViewController: UIViewController {

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
//        textView.becomeFirstResponder()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.whiteColor()

        setupNav()
        setupTextView()
        setupToolBar()

        // 监听键盘的通知
        // UIKeyboardWillChangeFrameNotification    // 此处选will, 与键盘同时移动, 而键盘的移动有个过程;
        // UIKeyboardDidChangeFrameNotification     // 此处选did则会滞后
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "changeNotification:", name: UIKeyboardWillChangeFrameNotification, object: nil)

        NSNotificationCenter.defaultCenter().addObserver(self, selector: "insertEmotion:", name: kNotificationTransformEmotion, object: nil)

        NSNotificationCenter.defaultCenter().addObserver(self, selector: "deleteEmotion:", name: kNotificationDeleteEmotion, object: nil)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
        // 解决dismiss时 键盘/表情滞后的bug
        textView.resignFirstResponder()
    }

    // MARK: - 设置导航栏
    private func setupNav() {
        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "返回", style: .Plain, target: self, action: "dismiss")
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "发布", style: .Plain, target: self, action: "publish")

        // 导航title
        let label = UILabel(frame: CGRectMake(0, 0, 200, 44))
        label.numberOfLines = 0
        label.textAlignment = .Center
        let str = "发布微博\n 一抹蚊子血"
        // 创建NSAttributedString对象, 是不可变的, 不能添加属性
//        let attribute = NSAttributedString(string: str)
        // 定义可变的
        let mutableAttribute = NSMutableAttributedString(string: str)
        // 添加属性
        mutableAttribute.addAttributes([NSFontAttributeName : UIFont.systemFontOfSize(18.0), NSForegroundColorAttributeName : UIColor.blackColor()], range: NSMakeRange(0, 4))
        mutableAttribute.addAttributes([NSFontAttributeName : UIFont.systemFontOfSize(14.0), NSForegroundColorAttributeName : UIColor.lightGrayColor()], range: NSMakeRange(6, str.characters.count - 6))
        label.attributedText = mutableAttribute
        navigationItem.titleView = label
    }

    @objc private func dismiss() {
        dismissViewControllerAnimated(true) { () -> Void in
        }
    }

    @objc private func publish() {
        // 判断有没有图片
        if chooseView.getImages().count > 0 {
            upload()
        } else {
            update()
        }
    }

    // 发布一条微博(无图)
    private func update() {

        /** POST        https://upload.api.weibo.com/2/statuses/update.json
        access_token	true	string	采用OAuth授权方式为必填参数，OAuth授权后获得。
        status          true	string	要发布的微博文本内容，必须做URLencode，内容不超过140个汉字。*/

//        // 遍历textView.attributedText
//        /*
//        range: 要遍历的字符串range
//        options: 选一个默认值
//        block
//        */
//
//        var publishString = String()
//        textView.attributedText.enumerateAttributesInRange(NSMakeRange(0, textView.attributedText.length), options: []) { (data, range, _) -> Void in
//
//            if let attachment = data["NSAttachment"] as? HBTextAttachment {
//                // 拼接发布表情
//                if let chs = attachment.emotion?.chs {
//                    publishString = publishString + chs
//                }
//            } else {
//                // 
//                let subString = (self.textView.text as NSString).substringWithRange(range)
//                publishString = publishString + subString
//            }
//        }
//        printLog(publishString)

        // 发布微博
        guard let access_token = HBOauthViewModel.shareInstance.access_token else {
            return
        }
        let params = ["access_token" : access_token, "status" : textView.getPublishTextString()]

        HBHTTPClient.request(.POST, URLString: "https://api.weibo.com/2/statuses/update.json", parameters: params, success: { (JSON) -> Void in
            printLog(JSON)
            SVProgressHUD.showInfoWithStatus("发布成功")
            }) { (error) -> Void in
                printLog(error)
                SVProgressHUD.showInfoWithStatus(error.description)
        }
    }

    // 上传图片并发布一条新微博
    private func upload() {

        /** POST        https://upload.api.weibo.com/2/statuses/upload.json
        source	false	string	采用OAuth授权方式不需要此参数，其他授权方式为必填参数，数值为应用的AppKey。
        access_token	false	string	采用OAuth授权方式为必填参数，其他授权方式不需要此参数，OAuth授权后获得。
        status	true	string	要发布的微博文本内容，必须做URLencode，内容不超过140个汉字。
        pic	true	binary	要上传的图片，仅支持JPEG、GIF、PNG格式，图片大小小于5M。
        
        请求必须用POST方式提交，并且注意采用multipart/form-data编码方式；
        非会员发表定向微博，分组成员数最多200。
        */

        guard let access_token = HBOauthViewModel.shareInstance.access_token else {
            return
        }
        let params = ["access_token" : access_token, "status" : textView.getPublishTextString()]

        // 图片放在表单中 (采用multipart/form-data编码)    // 有的公司不用表单, 把二进制图片的base64编码后的字符串, 以参数形式POST过去
        let image = chooseView.getImages().first
        // compressionQuality: 压缩质量 0~1.0, 无严格限制
        let data = UIImageJPEGRepresentation(image!, 0.3)

        HBHTTPClient.shareInstance.POST("https://upload.api.weibo.com/2/statuses/upload.json", parameters: params, constructingBodyWithBlock: { (formData) -> Void in
            /*
            data: 要上传的二进制
            name: 接口文档的字段名字
            fileName: 文件名称, 可随意填
            mimeType: mimeType
            */
            // 如果要一次性上传多张图片, 可以 for 循环这个方法
            formData.appendPartWithFileData(data!, name: "pic", fileName: "hehe.png", mimeType: "iamge/jpeg")

            }, success: { (_, JSON) -> Void in
//                printLog(JSON)
                SVProgressHUD.showInfoWithStatus("发布成功")
            }) { (_, error) -> Void in
                SVProgressHUD.showErrorWithStatus(error.description)
        }
    }

    // MARK: - 设置textView
    private func setupTextView() {
        // textView 的占位符有2种实现方式
        // 1. label
        // 2. 重绘

        view.addSubview(textView)
        // 设置
        textView.frame = view.bounds
        textView.font = UIFont.systemFontOfSize(16.0)
        textView.placeHolderStr = placeHoldString

        // 问题: 1)占位符没有消失, 2)占位符位置不对 --> 修改CGPoint
        // 有文字时, 占位符消失 -- 监听
        textView.delegate = self

        // textView和键盘相关
        textView.keyboardDismissMode = .OnDrag
        textView.alwaysBounceVertical = true    // 垂直拖拽时键盘消失

        // MARK: - 添加图片选择视图
        textView.addSubview(chooseView)
        chooseView.snp_makeConstraints { (make) -> Void in
            make.left.equalTo(textView).offset(HomeCellMargin)
            make.top.equalTo(textView).offset(100)
            make.width.height.equalTo(kScreenWidth - 2 * HomeCellMargin)
        }
    }

    // MARK: - 设置UIToolBar
    private func setupToolBar() {
        view.addSubview(toolBar)
        view.backgroundColor = UIColor.darkGrayColor()

        toolBar.snp_makeConstraints { (make) -> Void in
            make.left.right.bottom.equalTo(view)
            make.height.equalTo(44)
        }

        // 数据源形式
        let itemSettings = [["imageName": "compose_toolbar_picture", "action": "choosePicture"],
            ["imageName": "compose_mentionbutton_background"],
            ["imageName": "compose_trendbutton_background"],
            ["imageName": "compose_emoticonbutton_background", "action": "inputEmoticon"],
            ["imageName": "compose_addbutton_background"]]
        // 遍历item
        var items = [UIBarButtonItem]()
        for itemSetting in itemSettings {
            let button = UIButton(type: UIButtonType.Custom)
            let imageName = itemSetting["imageName"]
            button.setImage(UIImage(named: imageName!), forState: .Normal)
            button.setImage(UIImage(named: "\(imageName)_highlighted"), forState: .Highlighted)
            // 运行后没显示, 因为button没有设置frame
            button.sizeToFit()
            // 点击方法
            let action = itemSetting["action"]
            if let oAction = action {
                button.addTarget(self, action: Selector(oAction), forControlEvents: .TouchUpInside)
            }

            let item = UIBarButtonItem(customView: button)

            items.append(item)
            // 添加弹簧间隔
            items.append(UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil))
        }
        // 循环外减少一个弹簧
        items.removeLast()

        toolBar.items = items
    }

    // MARK: - 懒加载
    private lazy var textView: HBPlaceHoldTextView = HBPlaceHoldTextView()

    private lazy var toolBar: UIToolbar = UIToolbar()

    private lazy var chooseView: HBChooseView = {
        let chooseView = HBChooseView()
        // 循环引用: 闭包 -> HBPublishViewController -> chooseView -> 闭包
        // 三种方式: 
        // 1) [weak self]    -- weak
        // 2) [unowned self] -- assign
        // 3) weak var weakSelf = self
        weak var weakSelf = self
        chooseView.selectImgClosure = { ()->() in
            weakSelf?.choosePicture()
        }
        return chooseView
    }()

    private lazy var emotionView: HBEmotionView = {
        let view = HBEmotionView(frame: CGRectMake(0, 0, kScreenWidth,  216))
        return view
    }()

    // MARK: - deinit
    deinit {
        printLog("publishVc dismiss??")
        NSNotificationCenter.defaultCenter().removeObserver(self)
        /** 最好不要写在viewWillDisappear中
        当触发侧滑返回时会调用系统自带的viewWillDisappear:方法，在该方法中将监听键盘显示和隐藏的通知移除后，要是这时候用户取消了侧滑返回（即回到了原始状态），那么再点击界面上的textField唤出键盘，是不会发送键盘显示和隐藏的通知了，因为通知已被移除。。
        */
    }
}

// MARK: - UITextViewDelegate
extension HBPublishViewController: UITextViewDelegate {
    func textViewDidChange(textView: UITextView) {
        if self.textView.hasText() {
            self.textView.placeHolderStr = ""
        } else {
            self.textView.placeHolderStr = placeHoldString
        }
        // 重绘
        textView.setNeedsDisplay()
    }
}

// MARK: - 底部视图按钮的点击方法
extension HBPublishViewController {
    // 选择图片
    @objc private func choosePicture() {

        // 防止多余9张图片
        if chooseView.isFull() {
            return
        }

        /*
        PhotoLibrary(默认)   图库, 包含相册
        Camera              相机
        SavedPhotosAlbum    相册
        */
        if UIImagePickerController.isSourceTypeAvailable(.PhotoLibrary) {

            let imagePicker = UIImagePickerController()
            // 指定类型
            imagePicker.sourceType = .PhotoLibrary
            // 设置代理
            imagePicker.delegate = self

            // 跳转到指定视图
            presentViewController(imagePicker, animated: true, completion: { () -> Void in
            })
        }
    }

    // 表情键盘
    @objc private func inputEmoticon() {
        // 切换表情键盘和键盘
        textView.inputView == nil ? (textView.inputView = emotionView) : (textView.inputView = nil)
        // 调用启动方法
        textView.reloadInputViews()
        // 第一响应者, 弹出对应表情或键盘
        textView.becomeFirstResponder()
        printLog(textView.inputView)
    }
}

// MARK: - 图片选择代理方法 (两个代理)
extension HBPublishViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    // 注意: 需手动让控制器消失

    // 选择图片后 (已被移除, 但参数中含有image)
    func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {

        // 将image添加到chooseView
        chooseView.addImage(image)

        picker.dismissViewControllerAnimated(true) { () -> Void in
        }
    }

    // 选择完图片之后
//    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
//        picker.dismissViewControllerAnimated(true) { () -> Void in
//        }
//    }

    // 点击cancel时
    func imagePickerControllerDidCancel(picker: UIImagePickerController) {
        picker.dismissViewControllerAnimated(true) { () -> Void in
        }
    }

}

// MARK: - 控制器的通知方法
extension HBPublishViewController {
    @objc private func changeNotification(noti: NSNotification) {
//        printLog(noti.userInfo)
        /**
        键盘弹出时
            UIKeyboardFrameEndUserInfoKey: NSRect: {{0, 667}, {375, 216}}, 
            UIKeyboardAnimationDurationUserInfoKey: 0.25,
        键盘返回时
            UIKeyboardFrameEndUserInfoKey: NSRect: {{0, 409}, {375, 258}},
            UIKeyboardAnimationDurationUserInfoKey: 0.25,
        */

        // 通过 CGRectValue 获取键盘的 NSRect值
        let rect = noti.userInfo![UIKeyboardFrameEndUserInfoKey]!.CGRectValue

        // 根据键盘frame更新toolBar位置
        if rect.origin.y == kScreenHeight {
            toolBar.snp_updateConstraints(closure: { (make) -> Void in
                make.bottom.equalTo(view.snp_bottom).offset(0)
            })
        } else {
            toolBar.snp_updateConstraints(closure: { (make) -> Void in
                make.bottom.equalTo(view.snp_bottom).offset(-rect.size.height)
            })
        }

        // 添加约束动画
        UIView.animateWithDuration(0.25) { () -> Void in
            // 注意约束动画的调用
            self.toolBar.layoutIfNeeded()
        }

    }

    @objc private func insertEmotion(noti: NSNotification) {
        if let userInfo = noti.userInfo {
            // 默认as String转NSString 和 swift数组转NSArray
            // as! 
            // as? 后二者的选择标准看前边的返回类型
            let emotion = userInfo["emotion"] as? HBEmotion
            if let oEmotion = emotion {

//                // 表情图片
//                if let _ = oEmotion.png {
//                    let muAttribute = NSMutableAttributedString(attributedString: textView.attributedText)
//                    
//                    // 1. 创建附件对象
//                    let attachment = NSTextAttachment()
//                    // 1.1 拼接路径
//                    guard let path = oEmotion.path, png = oEmotion.png else {
//                        return
//                    }
//                    let imagePath = "\(path)/\(png)"
//                    // 1.2 设置属性
//                    attachment.image = UIImage(named: imagePath)
//                    // 1.3 修改图片bounds
//                    let lineHeight = textView.font?.lineHeight
//                    attachment.bounds = CGRectMake(0, -5, lineHeight!, lineHeight!)  // y的负值向下
//
//                    // 2. NSAttributeString对象
//                    let attribute = NSAttributedString(attachment: attachment)
//
//                    // 3. 拼接
////                    muAttribute.appendAttributedString(attribute)  // 末尾, 不能中间插入
////                    muAttribute.insertAttributedString(attribute, atIndex: Int)  // index不好获取
//                    let range = textView.selectedRange
//                    muAttribute.replaceCharactersInRange(range, withAttributedString: attribute)
//
//                    // 3.1 需要改muAttribute的属性
//                    muAttribute.addAttributes([NSFontAttributeName : textView.font!], range: NSMakeRange(0, muAttribute.length))
//
//                    // 4. 赋值
//                    textView.attributedText = muAttribute
//                    // 赋值之后恢复光标位置
//                    textView.selectedRange = NSMakeRange(range.location + 1, 0)
//
//                    // 隐藏占位文字
//                    // ①时间点 ②调用代理方法
//                    textView.delegate?.textViewDidChange!(textView)
//                }
//
//                // emoji图片
//                if let emoji = oEmotion.emoji {
//                    textView.replaceRange(textView.selectedTextRange!, withText: emoji)  // selectedTextRange
//                }

                textView.insertEmotion(oEmotion)
                
            }
        }
    }

    @objc private func deleteEmotion(noti: NSNotification) {
        textView.deleteBackward()
    }
}
